﻿using System.Collections.Generic;
using System.Globalization;

namespace Jayden.Dll.Web.PayPal
{
	public class PayPalRequest
	{
		//https://cms.paypal.com/au/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_Appx_websitestandard_htmlvariables
		private Dictionary<string, string> m_Variables = new Dictionary<string, string>();
		private List<PayPalPaymentLine> m_Lines = new List<PayPalPaymentLine>();

		public IEnumerable<string> Variables
		{
			get
			{
				foreach (KeyValuePair<string, string> pair in m_Variables)
					yield return pair.Key;
				for (int c = 0; c < m_Lines.Count; c++)
				{
					foreach (string variable in ItemVariables)
					{
						string value = m_Lines[c][variable];
						if (!string.IsNullOrWhiteSpace(value))
							yield return string.Format("{0}_{1}", variable, (c + 1));
					}
				}
				
			}
		}

		public IEnumerable<string> ItemVariables
		{
			get
			{
				yield return "amount";
				yield return "discount_amount";
				yield return "discount_amount2";
				yield return "discount_rate";
				yield return "discount_rate2";
				yield return "discount_num";
				yield return "item_name";
				yield return "item_number";
				yield return "quantity";
				yield return "shipping";
				yield return "shipping2";
				yield return "tax";
				yield return "tax_rate";
				yield return "undefined_quantity";
				yield return "weight";
				yield return "weight_unit";
			}
		}

		public string this[string key]
		{
			get 
			{
				string value;
				if (m_Variables.TryGetValue(key, out value))
					return value;
				for (int c = 0; c < m_Lines.Count; c++)
				{
					string suffix = "_" + (c + 1).ToString();
					if (key.EndsWith(suffix))
					{
						string itemKey = key.Substring(0, key.Length - suffix.Length);
						return m_Lines[c][itemKey];
					}
				}
				return null;
			}
			set
			{

				for (int c = 0; c < m_Lines.Count; c++)
				{
					string suffix = "_" + (c + 1).ToString();
					if (key.EndsWith(suffix))
					{
						string itemKey = key.Substring(0, key.Length - suffix.Length);
						m_Lines[c][itemKey] = value;
						return;
					}
				}
				if (value == null)
					m_Variables.Remove(key);
				else if (m_Variables.ContainsKey(key))
					m_Variables[key] = value;
				else
					m_Variables.Add(key, value);
			}
		}

		public static double FromHtml(string text)
		{
			if (text == null)
				return 0;
			return double.Parse(text, CultureInfo.InvariantCulture);
		}
		public static string ToHtml(double value)
		{
			if (value == 0)
				return null;
			return value.ToString("F2", CultureInfo.InvariantCulture);
		}

		public string Cmd { get { return this["cmd"]; } set { this["cmd"] = value; } }

		public string Business { get { return this["business"]; } set { this["business"] = value; } }

		public string NotifyUrl { get { return this["notify_url"]; } set { this["notify_url"] = value; } }
		public string ReturnUrl { get { return this["return"]; } set { this["return"] = value; } }
		public string ShoppingUrl { get { return this["shopping_url"]; } set { this["shopping_url"] = value; } }
		public string CurrencyCode { get { return this["currency_code"]; } set { this["currency_code"] = value; } }
		public string Custom { get { return this["custom"]; } set { this["custom"] = value; } }
		public double Handling { get { return FromHtml(this["handling"]); } set { this["handling"] = ToHtml(value); } }
		public string Invoice { get { return this["invoice"]; } set { this["invoice"] = value; } }
		public double TaxCart { get { return FromHtml(this["tax_cart"]); } set { this["tax_cart"] = ToHtml(value); } }
		public double WeightCart { get { return FromHtml(this["weight_cart"]); } set { this["weight_cart"] = ToHtml(value); } }
		public string WeightUnit { get { return this["weight_unit"] ?? PayPalHelper.Lbs; } set { this["weight_unit"] = value; } }

		public double DiscountAmountCart { get { return FromHtml(this["discount_amount_cart"]); } set { this["discount_amount_cart"] = ToHtml(value); } }
		public double DiscountRateCart { get { return FromHtml(this["discount_rate_cart"]); } set { this["discount_rate_cart"] = ToHtml(value); } }

		public bool UploadCart { get { return this["upload"] == "1"; } set { this["upload"] = value ? "1" : null; } }
		public bool AddCart { get { return this["add"] == "1"; } set { this["add"] = value ? "1" : null; } }
		public bool DisplayCart { get { return this["display"] == "1"; } set { this["display"] = value ? "1" : null; } }




		public void AddPayPalPaymentLine(PayPalPaymentLine line) { m_Lines.Add(line); }

		public void AddPayPalPaymentLine(IEnumerable<PayPalPaymentLine> lines)
		{
			foreach (PayPalPaymentLine line in lines)
				AddPayPalPaymentLine(line);
		}

		public Uri GetUri(bool sandbox = false)
		{
			Uri uri = new Uri(sandbox ? PayPalHelper.SandBoxUrl : PayPalHelper.Url, false);
			foreach (string variable in Variables)
				uri[variable] = this[variable];
			return uri;
		}

	}
}
